/*================================================================================
*
*
*
*
*
* 项目名称:  210605F7LVGL
* 文件名称:  TP_GT917S.c
* 创建日期:  Aug 8, 2021
* 文件描述:
*
================================================================================*/
#include "main.h"
#include "gpio.h"
#include "i2c.h"
#include "printUART.h"

#include "TP_GT917S.h"

#define GT917S_I2C_ADR                0XBA

#define GT917S_REG_REQ                0x8044
#define GT917S_REG_CFG                0x8050
#define GT917S_REG_STATE              0x814E

typedef enum tag_GT917S_I2C_STATE
{
  I2C_RD_STATE_REG,
  I2C_WR_STATE_REG,
  I2C_RD_REQ_REG,
  I2C_WR_REQ_REG,

  I2C_STATE_ENUM,
}TpI2cState_e;

typedef struct tag_touch_data
{
  uint8_t u8TrkId;
  uint16_t u16x;
  uint16_t u16y;
}TouchData_t;

//-private data-------------------------------------------------------
static TpI2cState_e s_eI2cState=I2C_RD_STATE_REG;
static uint8_t s_u8RegData[81];
static uint8_t s_flgI2cRxOk=0, s_flgI2cTxOk=0;
static TouchData_t s_TouchPts[10];

//-public data--------------------------------------------------------
uint8_t flgTouchEvent=0; //触摸中断后接收I2C数据完成标志
TpTouchPar_t TpTouchPar;


/* @brief 初始化GT917S地址时序，另地址为
 * @param
 */
void GT917S_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  uint8_t u8TsCfg[8]={GT917S_REG_CFG>>8, GT917S_REG_CFG&0xFF, 0x00, 0x20, 0x03, 0xE0, 0x01, 0x05};
  uint8_t u8Tmp[8]={GT917S_REG_CFG>>8, GT917S_REG_CFG&0xFF};

  HAL_Delay(1);
  HAL_GPIO_WritePin(TP_nRST_GPIO_Port, TP_nRST_Pin, GPIO_PIN_SET);
  HAL_Delay(6);

  GPIO_InitStruct.Pin = TP_INT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(TP_INT_GPIO_Port, &GPIO_InitStruct);

  // TODO: 使用I2C配置触摸屏0x8050-0x8055这些寄存器
  if(HAL_OK != HAL_I2C_Master_Transmit(&hi2c2, GT917S_I2C_ADR, u8TsCfg, 8, 100))
  {
    printUART("gt917s i2c tx failed\n");
  }

  HAL_Delay(10);

  HAL_I2C_Master_Transmit(&hi2c2, GT917S_I2C_ADR, u8Tmp, 2, 100);
  HAL_I2C_Master_Receive(&hi2c2, GT917S_I2C_ADR, &u8Tmp[2], 6, 100);

  printUART("config data receive in reg: ");
  for(uint8_t i=2; i<8; i++)
  {
    printUART("0x%X, ", u8Tmp[i]);
  }
  printUART("\n");


  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

/*
 * @brief 触摸处理
 */
void GT917S_TouchProcess(void)
{
  uint8_t u8TsData[83] = {GT917S_REG_STATE>>8, GT917S_REG_STATE&0xFF};
  uint8_t u8NumTouchPts=0;
  uint8_t i=0;
  uint16_t u16Coords[10][2] = {0};  // { {x0, y0}...{x9, y9} }

  HAL_I2C_Master_Transmit(&hi2c2, GT917S_I2C_ADR, u8TsData, 2, 10);
  HAL_I2C_Master_Receive(&hi2c2, GT917S_I2C_ADR, &u8TsData[2], 81, 10);

  printUART("touch state reg: 0x%X\n", u8TsData[2]);

  if(u8TsData[2]==0)
  {
    u8TsData[0] = GT917S_REG_REQ>>8;
    u8TsData[1] = GT917S_REG_REQ&0xFF;
    HAL_I2C_Master_Transmit(&hi2c2, GT917S_I2C_ADR, u8TsData, 2, 10);
    HAL_I2C_Master_Receive(&hi2c2, GT917S_I2C_ADR, &u8TsData[2], 1, 10);

    printUART("touch req reg: 0x%X\n", u8TsData[2]);

    if(u8TsData[2]==0x01)
    {
      u8TsData[2] = 0;
      HAL_I2C_Master_Transmit(&hi2c2, GT917S_I2C_ADR, u8TsData, 3, 10);
    }
  }
  else if(u8TsData[2]&0x80) //Buffer state
  {
    u8NumTouchPts = u8TsData[2]&0x0F;

    for(i=0; i<u8NumTouchPts; i++)
    {
      u16Coords[i][0] = u8TsData[8*i+4]|(u8TsData[8*i+5]<<8);
      u16Coords[i][1] = u8TsData[8*i+6]|(u8TsData[8*i+7]<<8);

      s_TouchPts[i].u8TrkId = u8TsData[8*i+3]&0x0F;

      printUART("touch point %d coordinate, x: %d, y: %d, track id: %d\n", i, u16Coords[i][0], u16Coords[i][1], s_TouchPts[i].u8TrkId);
    }

    u8TsData[2] = 0;
    HAL_I2C_Master_Transmit(&hi2c2, GT917S_I2C_ADR, u8TsData, 3, 10);
  }
}

/********************************************************************************
*函数功能:
*修改记录:
*日期:                             作者:                             摘要:
      Aug 14, 2021      YummoShin         Create
********************************************************************************/
void GT917S_EventCheck(void)
{
  static uint8_t s_flgReadStart=0;
  static uint8_t s_u8RegAdr[3] = {GT917S_REG_STATE>>8, GT917S_REG_STATE&0xFF};
  static uint8_t s_u8PreNum=0;

  uint8_t u8NumTouchPts=0;
  uint8_t i=0;

  if(flgTouchEvent)
  {
    if(HAL_NVIC_GetActive(EXTI15_10_IRQn))
    {
      HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
    }

    switch (s_eI2cState) {
      case I2C_RD_STATE_REG:
        if(0==s_flgReadStart)
        {
          s_flgReadStart = 1;
          s_flgI2cRxOk = 0;

          s_u8RegAdr[0] = GT917S_REG_STATE>>8;
          s_u8RegAdr[1] = GT917S_REG_STATE&0xFF;
          HAL_I2C_Master_Seq_Transmit_IT(&hi2c2, GT917S_I2C_ADR, s_u8RegAdr, 2, I2C_SOFTEND_MODE);
        }
        else if(s_flgReadStart) //已发出i2c读请求等待中断置位完成标志
        {
          if(s_flgI2cRxOk)
          {
            s_flgReadStart = 0;
            s_flgI2cRxOk = 0;

            if(s_u8RegData[0]==0)
            {
              s_eI2cState = I2C_RD_REQ_REG;
              s_u8RegAdr[0] = GT917S_REG_REQ>>8;
              s_u8RegAdr[1] = GT917S_REG_REQ&0xFF;
              HAL_I2C_Master_Seq_Transmit_IT(&hi2c2, GT917S_I2C_ADR, s_u8RegAdr, 2, I2C_SOFTEND_MODE);
            }
            else if(s_u8RegData[0]&0x80)
            {
              u8NumTouchPts = s_u8RegData[0]&0x0F;
              for(i=0; i<u8NumTouchPts; i++)
              {
                s_TouchPts[i].u8TrkId = s_u8RegData[i*8+1]&0x0F;
                s_TouchPts[i].u16x = s_u8RegData[i*8+2]|(s_u8RegData[i*8+3]<<8);
                s_TouchPts[i].u16y = s_u8RegData[i*8+4]|(s_u8RegData[i*8+5]<<8);
              }

              if(s_u8PreNum<=u8NumTouchPts && u8NumTouchPts>0)
              {
                TpTouchPar.u16x = s_TouchPts[0].u16x;
                TpTouchPar.u16y = s_TouchPts[0].u16y;
                TpTouchPar.u8TouchState = 1;
              }
              else if(s_u8PreNum>u8NumTouchPts && u8NumTouchPts>0) //有点减少
              {
                if(s_TouchPts[0].u8TrkId!=0)
                {
                  TpTouchPar.u8TouchState = 0;
                }
                else
                {
                  TpTouchPar.u16x = s_TouchPts[0].u16x;
                  TpTouchPar.u16y = s_TouchPts[0].u16y;
                  TpTouchPar.u8TouchState = 1;
                }
              }
              else if(u8NumTouchPts==0)
              {
                TpTouchPar.u8TouchState = 0;
              }
              s_u8PreNum = u8NumTouchPts;

              s_eI2cState = I2C_WR_STATE_REG;
              s_u8RegAdr[0] = GT917S_REG_STATE>>8;
              s_u8RegAdr[1] = GT917S_REG_STATE&0xFF;
              s_u8RegAdr[2] = 0;
              HAL_I2C_Master_Seq_Transmit_IT(&hi2c2, GT917S_I2C_ADR, s_u8RegAdr, 3, I2C_AUTOEND_MODE);
            }
          }
        }
        break;

      case I2C_RD_REQ_REG:
        if(s_flgI2cRxOk)
        {
          s_flgI2cRxOk = 0;
          if(s_u8RegData[0]==0x01)
          {
            s_eI2cState = I2C_WR_REQ_REG;
            s_u8RegAdr[0] = GT917S_REG_REQ>>8;
            s_u8RegAdr[1] = GT917S_REG_REQ&0xFF;
            s_u8RegAdr[2] = 0;
            HAL_I2C_Master_Transmit_IT(&hi2c2, GT917S_I2C_ADR, s_u8RegAdr, 3); //清零 REQ REG
          }
          else
          {
            s_eI2cState = I2C_RD_STATE_REG;
            flgTouchEvent = 0;
            HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
          }
        }
        break;

      case I2C_WR_STATE_REG:
      case I2C_WR_REQ_REG:
        if(s_flgI2cTxOk)
        {
          s_flgI2cTxOk = 0;
          s_eI2cState = I2C_RD_STATE_REG;
          flgTouchEvent = 0;

          //printUART("coordinate x: %d, y: %d, state: %d\n", TpTouchPar.u16x, TpTouchPar.u16y, TpTouchPar.u8TouchState);

          HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
        }
        break;

      default:
        break;
    }
  }
}

/**
  * @brief  Master Tx Transfer completed callback.
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
  *                the configuration information for the specified I2C.
  * @retval None
  */
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
  /* Prevent unused argument(s) compilation warning */
  switch (s_eI2cState)
  {
  case I2C_RD_STATE_REG: //发送寄存器地址完成
    HAL_I2C_Master_Seq_Receive_IT(hi2c, GT917S_I2C_ADR, s_u8RegData, 81, I2C_AUTOEND_MODE);
    break;

  case I2C_RD_REQ_REG:
    HAL_I2C_Master_Seq_Receive_IT(hi2c, GT917S_I2C_ADR, s_u8RegData, 1, I2C_AUTOEND_MODE);
    break;

  case I2C_WR_STATE_REG:
  case I2C_WR_REQ_REG:
    s_flgI2cTxOk = 1;
    break;
  default:
    break;
  }

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_I2C_MasterTxCpltCallback could be implemented in the user file
   */
}

/********************************************************************************
*函数功能:
*修改记录:
*日期:                             作者:                             摘要:
      2021年8月15日      YummoShin         Create
********************************************************************************/
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
  UNUSED(hi2c);

  switch (s_eI2cState)
  {
  case I2C_RD_STATE_REG: //接收数据完
  case I2C_RD_REQ_REG:
    s_flgI2cRxOk = 1;
    break;

  case I2C_WR_STATE_REG:
    break;

  case I2C_WR_REQ_REG:
    break;
  default:
    break;
  }
}
